import { _decorator, Component, Label, Node, ProgressBar, RichText, tween, UIOpacity, v3, Vec3 } from 'cc';
import { AudioManager } from '../AudioManager';
import I18n, { CountryType } from '../i18n/I18n';
import LocalizedLabel from '../i18n/LocalizedLabel';
import PoolManager from '../PoolManager';
import { RichTextAutoFontSize } from '../RichTextAutoResize';
import { NCPoint } from '../src/api/api.config.client';
import { ClientAPI } from '../src/api/client.api';
import ServiceAPI from '../src/api/service.api';
import { LuckywardPageNew } from '../src/ui/LuckywardPageNew';
import { Popup } from '../src/ui/page/popup';
import { Url } from '../Url';
import { GridBoardData } from './Block/BlockData';
import GlobalData from './GlobalData';
import { GridBlockMgr } from './GridBlockMgr';
import { Guide } from './Guide';
import { LocalStorageMgr } from './LocalStorageMgr';
import { TouchMgr } from './TouchMgr';
const { ccclass, property } = _decorator;

@ccclass('MainGameLogic')

export class MainGameLogic extends Component {

    /** 单例模式 */
    private static _ins: MainGameLogic;
    constructor() {
        super();
        MainGameLogic._ins = this;
    }
    public static get ins(): MainGameLogic {
        if (!MainGameLogic._ins) {
            MainGameLogic._ins = new MainGameLogic();
        }
        return MainGameLogic._ins;
    }

    @property(Node)
    background: Node = null;

    @property(Node)
    guide: Node = null;
    @property(Label)
    curCashLabel: Label = null;
    @property(Label)
    curScoreLabel: Label = null;
    @property(Label)
    historyScoreLabel: Label = null;
    @property(Label)
    todayScoreLabel: Label = null;
    @property(Node)
    popPage: Node = null;
    @property(RichText)
    dialogLabel: RichText = null;
    /** 当前得分 */
    public curScore: number = 0;
    /** 特殊处理总钱数 */
    spaciCashTotal: number = 0;
    sssspaciCashTotal: number = 0;
    @property(Label)
    refrashPropLabel: Label = null;
    @property(Label)
    hummerPropLabel: Label = null;
    @property(ProgressBar)
    lotteryProgress: ProgressBar = null;
    @property(Label)
    lotteryProgressLabel: Label = null;
    @property(RichText)
    lottoryLabel: RichText = null;

    lotteryData: any = null;

    private lastReturnedIndex: number = 0;

    @property(Node)
    tarCashIcon: Node = null;
    @property(Node)
    tarPropRefrashIcon: Node = null;
    @property(Node)
    tarPropHummerIcon: Node = null;

    @property(Node)
    effectsContainer: Node = null;

    @property(Node)
    cashbtn: Node = null;

    propInUse: boolean = false;

    start() {
        if (!LocalStorageMgr.getItem(LocalStorageMgr.gameInitFinish_key)) {
            LocalStorageMgr.setItem(LocalStorageMgr.gameInitFinish_key, 1);
            ClientAPI.Point(NCPoint.GAMEINITFINISH, { userid: GlobalData.userId })
            ClientAPI.Point(NCPoint.GAMESTART, { userid: GlobalData.userId });
        }


        AudioManager.ins.play(Url.AUDIO.BGM, 1);
        this.gameStart();
    }

    update(deltaTime: number) {

    }

    gameStart() {
        // console.log(!GlobalData.isCommer, GlobalData.guideRecord >= 8);

        if (!GlobalData.isCommer || GlobalData.guideRecord >= 10) {
            GlobalData.isCommer = false;
            LocalStorageMgr.setItem(LocalStorageMgr.isCommer_key, GlobalData.isCommer);
            GridBlockMgr.ins.generateBoard_effect(GlobalData.lastGameBoard);
            this.scheduleOnce(() => {
                GridBlockMgr.ins.generateSpecificSelectionBlock(false)
            }, 2);
            this.guide.active = false;
            this.dialogLabel.node.active = true;
            tween(this.dialogLabel.node.parent.parent)
                .to(0.5, { position: v3(300, 15, 0) })
                .to(0.5, { position: v3(250, 15, 0) })
                .union()
                .repeatForever()
                .start()
        } else {
            console.log("开启新手引导");
            this.guide.active = true;
        }

        mtec.cc.adaptBackgroundNode(this.background);

        this.checkAndUpdateDailyHighScore(GlobalData.lastLoginDate);

        this.updateCashLabel(GlobalData.curCashTotal, 1);
        this.updatePropNum();
        this.updateDialogLabel();
        this.updateLotteryProgress()
    }

    gameOver() {
        this.scheduleOnce(async () => {
            await Popup.Gameoverpage();
        }, 1)

    }

    reStartGame() {
        this.curScore = 0;
        GlobalData.curScore = 0;
        LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore);
        this.updateScores(GlobalData.curScore)
        GridBlockMgr.ins.generateBoard_effect(GridBoardData.customizeBoardData5);
        this.scheduleOnce(() => {
            GridBlockMgr.ins.generateSpecificSelectionBlock(false)
        }, 2)
    }

    async createEleAddScoreEff(effPos: Vec3, scoreStr: string) {
        let addsecore = await PoolManager.getObject('labelTip');
        addsecore.setParent(this.effectsContainer);
        addsecore.setPosition(effPos);
        addsecore.angle = 0;
        addsecore.getComponent(Label).string = '+' + scoreStr;
        addsecore.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1300), 1, 1)
            .call(() => {
                PoolManager.putObject('labelTip', addsecore)
            })
            .start();
        // tween(addsecore)
        //     .parallel(
        //         tween().to(0.2, { positon: v3(this.randInt(-80, 80), 100, 0) }),
        //         tween().to(0.2, { angle: 360 }),
        //         tween().to(0.2, { scale: v3(6, 6, 1) })
        //     )
        //     .to(0.2, { scale: v3(5, 5, 1) })
        //     .delay(0.3)
        //     .call(() => {
        //         PoolManager.putObject('labelTip', addsecore)
        //     })
        //     .start();
    }

    async createConsecutiveEffect(effPos: Vec3, totalClearedLines: number) {
        if (!effPos) {
            return
        }
        let consecutiveEff;
        let name;
        if (totalClearedLines < 2) {
            return;
        }
        if (totalClearedLines >= 2 && totalClearedLines < 4) {
            //good
            consecutiveEff = await PoolManager.getObject('good');
            name = 'good'
        } else if (totalClearedLines >= 4 && totalClearedLines < 6) {
            //great
            consecutiveEff = await PoolManager.getObject('great');
            name = 'great'
        } else if (totalClearedLines >= 6 && totalClearedLines < 8) {
            //excellent
            consecutiveEff = await PoolManager.getObject('excellent');
            name = 'excellent'
        } else if (totalClearedLines >= 8 && totalClearedLines < 10) {
            //amazing
            consecutiveEff = await PoolManager.getObject('amazing');
            name = 'amazing'
        } else if (totalClearedLines >= 10) {
            //unbelievable
            consecutiveEff = await PoolManager.getObject('unbelievable');
            name = 'unbelievable'
        }

        consecutiveEff.setParent(this.effectsContainer);
        consecutiveEff.setPosition(effPos);
        consecutiveEff.angle = 0;
        consecutiveEff.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1200), 1, 1)
            .call(() => {
                PoolManager.putObject(name, consecutiveEff)
            })
            .start();
        // tween(consecutiveEff)
        //     .parallel(
        //         tween().to(0.2, { angle: 360 }),
        //         tween().to(0.2, { scale: v3(0.8, 0.8, 1) })
        //     )
        //     .to(0.2, { scale: v3(0.7, 0.7, 1) })
        //     .delay(0.3)
        //     .call(() => {
        //         PoolManager.putObject(name, consecutiveEff)
        //     })
        //     .start();
    }

    async createLuckyWardPage(config) {
        let page = await PoolManager.getObject('LuckywardPage');
        page.setParent(this.effectsContainer);
        page.setPosition(v3(0, 0, 0));
        let luckypageCom = page.getComponent(LuckywardPageNew);
        luckypageCom.pageConfig = config;
        luckypageCom.init();
    }

    //  生成一个tip吐司、
    async createOneTipTpast(str: string, insert: string = null) {
        let tip: Node = await PoolManager.getObject('tip');
        tip.setParent(this.effectsContainer);
        tip.setPosition(v3(0, 0, 0));
        tip.getComponent(UIOpacity).opacity = 255;
        let tiplabel = tip.children[0].getComponent(Label)
        let localizedLabel = tiplabel.node.getComponent(LocalizedLabel);
        localizedLabel.setTextKeyAndOption(str, insert);

        tween(tip)
            .delay(0.5)
            .to(0.5, { position: v3(0, 50, 0) })
            .call(() => {
                PoolManager.putObject('tip', tip)
            })
            .start()

        tween(tip.getComponent(UIOpacity))
            .delay(0.5)
            .to(0.5, { opacity: 0 })
            .start()
    }

    //  生成一个块消除特效
    async createOneBlockEfEffect1(blocknode: Node) {
        let tarEfPos = TouchMgr.ins.getNodeAToNodeBPoint(blocknode, this.effectsContainer);
        let blockef = await PoolManager.getObject('ef');
        blockef.setParent(this.effectsContainer);
        blockef.setPosition(tarEfPos);
        blockef.setScale(0.7, 0.7, 1);
        blockef.active = true;

        tween(blockef)
            .by(this.randFloat(0.1, 0.3), { position: v3(this.randInt(-100, 100), this.randInt(200, 300), 0) })
            .delay(0.1)
            .by(this.randFloat(0.9, 1.5), { position: v3(0, -this.randInt(2000, 2500), 0) })
            .call(() => {
                // 确保动画执行完后再回收
                if (blockef.active) {
                    blockef.active = false;
                    PoolManager.putObject('ef', blockef);
                } else {
                    console.warn('blockef is already inactive, potential double call to recovery.');
                }
            })
            .start();
    }
    async createOneBlockEfEffect(blocknode: Node) {
        let tarEfPos = TouchMgr.ins.getNodeAToNodeBPoint(blocknode, this.effectsContainer);
        let blockef = await PoolManager.getObject('ef');
        blockef.setParent(this.effectsContainer);
        blockef.setPosition(tarEfPos);
        blockef.setScale(0.7, 0.7, 1);
        blockef.active = true;
        blockef.qtJumpDistance(new Vec3(this.randInt(-300, 300), -this.randInt(1000, 1500), 0), this.randInt(800, 1000), 1, 1)
            .call(() => {
                // 确保动画执行完后再回收
                PoolManager.putObject('ef', blockef);
            })
            .start();
    }

    randInt(min: number, max: number = undefined): number {
        if (max === undefined) {
            max = min;
            min = 0;
        }
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min;
    }
    randFloat(min: number, max: number = undefined): number {
        if (max === undefined) {
            max = min;
            min = 0;
        }
        return Math.random() * (max - min) + min;
    }

    /**
     * 获得道具效果
     * @param type 道具类型
     * @param effectpos 初始点
     * @returns
     */
    async showPropEffect(type: number, effectpos: Vec3) {
        if (!effectpos) {
            return
        }
        let tarPropPos: Vec3
        let eff: Node
        if (type == 0) {
            tarPropPos = TouchMgr.ins.getNodeAToNodeBPoint(this.refrashPropLabel.node.parent, this.effectsContainer);
            eff = await PoolManager.getObject("refresh")
        } else {
            tarPropPos = TouchMgr.ins.getNodeAToNodeBPoint(this.hummerPropLabel.node.parent, this.effectsContainer);
            eff = await PoolManager.getObject("hummer")
        }
    }
    /**
     * 使用锤子道具特效
     * @param targetPos 飞向目标位置
     */
    async usePropHummerEffect(targetPos: Vec3, call) {

        let hummer = await PoolManager.getObject('hummer');
        hummer.setParent(this.effectsContainer);
        hummer.setPosition(v3(0, 0, 0));
        hummer.setScale(2, 2, 1);
        hummer.angle = 0;
        tween(hummer)
            .delay(0.2)
            .parallel(
                tween().to(0.3, { position: targetPos }),
                tween().to(0.3, { angle: -30 })
            )
            .call(() => {
                AudioManager.ins.playOneShot(Url.AUDIO.SFX8, 1);
            })
            .to(0.2, { angle: 70 })
            .call(() => {
                call();
                PoolManager.putObject('hummer', hummer);
            })
            .start()
    }
    /**
     * 展示获取道具 效果
     * @param propType 道具类型
     * @param effectpos 初始位置
     */
    async showGetPropEffect(propType: 'Refrash' | 'Hummer', effectpos: Vec3) {
        if (!effectpos) {
            return
        }
        let tarPropPos: Vec3;
        let effect: Node;
        if (propType == 'Refrash') {
            tarPropPos = TouchMgr.ins.getNodeAToNodeBPoint(this.tarPropRefrashIcon, this.effectsContainer);
            effect = await PoolManager.getObject('refresh')
        } else {
            tarPropPos = TouchMgr.ins.getNodeAToNodeBPoint(this.tarPropHummerIcon, this.effectsContainer);
            effect = await PoolManager.getObject('hummer')
        }
        effect.setParent(this.effectsContainer);
        effect.setPosition(effectpos);
        effect.setScale(2, 2, 1)
        tween(effect)
            .delay(0.2)
            .parallel(
                tween().to(0.5, { scale: v3(1, 1, 1) }),
                tween().to(0.5, { position: tarPropPos })
            )
            .start();
        tween(effect.getComponent(UIOpacity))
            .delay(0.7)
            .to(0.5, { opacity: 0 })
            .call(() => {
                AudioManager.ins.playOneShot(Url.AUDIO.SFX6, 1);
                PoolManager.putObject(effect.name, effect);
            })
            .start()
    }

    /**
     * 展示 飞钱效果
     * @param effectpos 初始位置
     * @returns
     */
    async shwoGetCashEffect(effectpos: Vec3) {
        if (!effectpos) {
            return
        }
        let tarCashPos = TouchMgr.ins.getNodeAToNodeBPoint(this.tarCashIcon, this.effectsContainer);

        effectpos.add(v3(0, -100, 0));
        for (let i = 0; i < 6; i++) {
            setTimeout(async () => {
                let casheffect = await PoolManager.getObject('casheffect');
                casheffect.setParent(this.effectsContainer);
                casheffect.setPosition(effectpos);
                casheffect.setScale(0.3, 0.3, 1)
                let midpos = this.getRandomPositionAround(effectpos, 200);
                tween(casheffect)
                    .to(0.7, { scale: v3(0.5, 0.5, 1) })
                    .start();
                tween(casheffect)
                    .to(0.1, { position: midpos })
                    .delay(0.1)
                    .to(0.5, { position: tarCashPos })
                    .call(() => {
                        AudioManager.ins.playOneShot(Url.AUDIO.SFX6, 1);
                        PoolManager.putObject('casheffect', casheffect);
                        tween(this.tarCashIcon)
                            .to(0.05, { scale: v3(0.6, 0.6, 1) })
                            .to(0.05, { scale: v3(0.5, 0.5, 1) })
                            .start();
                    })
                    .start();
            }, i * 100);
        }

    }
    /** 左上角加钱 */
    async createLabelTip1(_cashAmount) {
        let tarCashPos = TouchMgr.ins.getNodeAToNodeBPoint(this.tarCashIcon, this.effectsContainer);
        let labelTip1 = await PoolManager.getObject('labelTip1');
        labelTip1.getComponent(Label).string = '+' + MainGameLogic.ins.formatCashValue(_cashAmount);
        labelTip1.getComponent(UIOpacity).opacity = 255;
        labelTip1.setParent(this.effectsContainer);
        labelTip1.setPosition(tarCashPos.add(v3(250, 0, 0)));
        tween(labelTip1)
            .by(0.5, { position: v3(0, 50, 0) })
            .delay(0.2)
            .removeSelf()
            .start()
        tween(labelTip1.getComponent(UIOpacity))
            .delay(0.5)
            .to(0.2, { opacity: 0 })
            .start()
    }

    getRandomPositionAround(origin: Vec3, radius: number): Vec3 {
        // 确保最小半径不小于50
        const minRadius = 50;
        const finalRadius = Math.max(minRadius, radius);

        // 随机生成角度（以弧度为单位）
        const angle = Math.random() * 2 * Math.PI;

        // 在[minRadius, finalRadius]范围内生成距离
        const distance = minRadius + Math.random() * (finalRadius - minRadius);

        // 计算新位置的偏移量
        const offsetX = Math.cos(angle) * distance;
        const offsetY = Math.sin(angle) * distance;

        // 返回新位置
        return new Vec3(origin.x + offsetX, origin.y + offsetY, origin.z);
    }

    updatePropNum() {
        this.refrashPropLabel.string = 'x' + GlobalData.refrashPropNum.toString();
        this.hummerPropLabel.string = 'x' + GlobalData.hummerPropNum.toString();
        let refrashadicon = this.refrashPropLabel.node.parent.getChildByName('adicon');
        let hummeradicon = this.hummerPropLabel.node.parent.getChildByName('adicon');
        if (GlobalData.refrashPropNum == 0) {
            this.refrashPropLabel.node.active = false;
            refrashadicon.active = true;
        } else {
            this.refrashPropLabel.node.active = true;
            refrashadicon.active = false;
        }
        if (GlobalData.hummerPropNum == 0) {
            this.hummerPropLabel.node.active = false;
            hummeradicon.active = true;
        } else {
            this.hummerPropLabel.node.active = true;
            hummeradicon.active = false;
        }
    }

    async useRefrashProp(event, _gameOverUse = false) {
        if (_gameOverUse) {
            AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1);
            GridBlockMgr.ins.generateSpecificSelectionBlock(true);
            return
        }

        if (this.propInUse) {
            return
        }
        if (GlobalData.refrashPropNum > 0) {
            this.propInUse = true;
            AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1);
            GridBlockMgr.ins.generateSpecificSelectionBlock(true);
            GlobalData.refrashPropNum--;
            this.updatePropNum();

        } else {
            let isCom = await ClientAPI.AD("incentive",'prop');
            if (isCom) {
                GlobalData.refrashPropNum++;
                this.updatePropNum();
            }
        }
        LocalStorageMgr.setItem(LocalStorageMgr.refrashPropNum_key, GlobalData.refrashPropNum)
    }

    async useHummerProp(event, _gameOverUse = false) {
        // console.log(_gameOverUse);

        if (_gameOverUse) {
            GridBlockMgr.ins.chechAndEliminateRandomArea();
            return
        }
        if (this.propInUse) {
            return
        }
        if (GlobalData.hummerPropNum > 0) {
            this.propInUse = true;
            let isUse = GridBlockMgr.ins.chechAndEliminateRandomArea();
            // console.log(isUse);
            if (isUse) {
                GlobalData.hummerPropNum--;
                this.updatePropNum();
            }

        } else {
            let isCom = await ClientAPI.AD("incentive",'prop');
            if (isCom) {
                GlobalData.hummerPropNum++;
                this.updatePropNum();
            }
        }
        LocalStorageMgr.setItem(LocalStorageMgr.hummerPropNum_key, GlobalData.hummerPropNum)
    }

    /**
     * 获取交替返回的 forcePopIntervalList 的值
     * @param dataList - 包含 redStartCount, redEndCount, 和 forcePopIntervalList 的数据数组
     * @param redPacket - GlobalData.redPacket 的值
     * @returns forcePopIntervalList 中交替返回的值，或 undefined 如果没有找到匹配的区间
     */
    public getNextIntervalValue(luckyWardNorgetTimes: number, dataList: Array<{ redStartCount: number, redEndCount: number, forcePopIntervalList: number[] }>, redPacket: number): boolean {
        // 找到 redPacket 所属的区间
        const matchingData = dataList.find(data => redPacket >= data.redStartCount && redPacket <= data.redEndCount);

        if (matchingData) {
            // 获取 forcePopIntervalList 数组
            const intervalList = matchingData.forcePopIntervalList;

            // 根据 lastReturnedIndex 交替返回数组中的值
            const valueToReturn = intervalList[this.lastReturnedIndex];
            if (luckyWardNorgetTimes >= valueToReturn) {
                // 更新 lastReturnedIndex，为下次调用做准备
                this.lastReturnedIndex = (this.lastReturnedIndex + 1) % intervalList.length;
                return true;
            } else {
                return false
            }
        }
        // 如果没有找到匹配的区间，返回 undefined
        return false;
    }


    /** 更新对话框 */
    async updateDialogLabel() {

        let config =  await ServiceAPI.WithdrawConfig(GlobalData.userId);
        let tarCashAmount = config.cashWithdrawConfig[0].cashAmount;

        // if (config.cashWithdrawConfig.length>2) {
        //     this.dialogLabel.node.parent.active = false;
        // }else{
        //     this.dialogLabel.node.parent.active = true;
        // }

        let needCash = tarCashAmount - GlobalData.curCashTotal
        if (needCash <= 0) {
            tarCashAmount = config.cashWithdrawConfig[1].cashAmount;
        }
        let localizedLabel = this.dialogLabel.node.getComponent(LocalizedLabel);
        localizedLabel.setTextKeyAndOption("home_diolog_Rtext", MainGameLogic.ins.formatCashValue(tarCashAmount - GlobalData.curCashTotal), MainGameLogic.ins.formatCashValue(tarCashAmount));
        this.dialogLabel.node.getComponent(RichTextAutoFontSize).adjustFontSize();
    }

    /** 每次消除获取奖励 */
    public async getElimitateCash() {
        let config = await ServiceAPI.EliminateReport(GlobalData.userId, GlobalData.isCommer);
        // console.log("每次消除奖励：", config);
        // console.log('引导步数：', GlobalData.guideRecord);
        // console.log(config.cashTotal, this.sssspaciCashTotal, GlobalData.curCashTotal + config.cashTotal - this.sssspaciCashTotal);
        if (GlobalData.guideRecord == 9) {
            // console.log("特殊处理步骤");
            // this.spaciCashTotal = config.cashTotal;
            // this.updateCashLabel(config.cashTotal - this.sssspaciCashTotal);
        } else {
            // console.log("正常步骤");
            // this.updateCashLabel(config.cashTotal);
        }
    }

    /** 检测引导和合成次数 */
    public async detectGuideAndElimiTimes(add_tempel_lotNum: number) {
        GlobalData.elimiTimes++;
        this.updateMissionStatus(1, GlobalData.elimiTimes);
        LocalStorageMgr.setItem(LocalStorageMgr.elimiTimes_key, GlobalData.elimiTimes);
        // console.log(add_tempel_lotNum);
        GlobalData.tempElimiTimes_lottery += add_tempel_lotNum;
        // console.log(GlobalData.tempElimiTimes_lottery);
        LocalStorageMgr.setItem(LocalStorageMgr.tempElimiTimes_lottery_key, GlobalData.tempElimiTimes_lottery);
        if (!GlobalData.isCommer) {
            GlobalData.tempElimiTimes_lucky++;
            LocalStorageMgr.setItem(LocalStorageMgr.tempElimiTimes_lucky_key, GlobalData.tempElimiTimes_lucky);
            //用于顺序执行，放置弹窗冲撞
            await this.detectEliminPopLuckyWardPage();
        }
        await this.detectEliminPopLotteryWardPage();
        if (GlobalData.isCommer && GlobalData.elimiTimes < 4) {
            Guide.ins.completeCurGuide(GlobalData.elimiTimes + 1);
        } else if (GlobalData.isCommer && GlobalData.elimiTimes == 4) {
            Guide.ins.completeCurGuide(9);
        }
    }

    /** 检测消除次数，弹出幸运奖励面板 */
    async detectEliminPopLuckyWardPage() {
        if (GlobalData.tempElimiTimes_lucky >= GlobalData.luckyWardPageInterval) {
            //  server获取幸运弹窗奖励
            let config = await ServiceAPI.ForcePopConfig(GlobalData.userId);
            // await Popup.Luckywardpage(config);
            this.createLuckyWardPage(config);
            GlobalData.tempElimiTimes_lucky = 0;
            LocalStorageMgr.setItem(LocalStorageMgr.tempElimiTimes_lucky_key, GlobalData.tempElimiTimes_lucky);
        }
    }

    /** 检测消除次数，弹出抽奖面板 */
    async detectEliminPopLotteryWardPage() {
        await this.updateLotteryProgress();
    }

    /** 更新抽奖进度 */
    public async updateLotteryProgress() {
        this.lotteryData = GlobalData.getDataStore().ConfCommon.lotteryConfig;
        // console.log(this.lotteryData);

        const curLotteryTimes = GlobalData.curlotteryTimes;
        // console.log(curLotteryTimes);
        for (let rule of this.lotteryData) {
            if (curLotteryTimes >= rule.minimum && curLotteryTimes <= rule.maximum) {
                const progressValue = GlobalData.tempElimiTimes_lottery / rule.needElimTimes;
                this.lotteryProgress.progress = progressValue;
                this.lotteryProgressLabel.string = `${GlobalData.tempElimiTimes_lottery}/${rule.needElimTimes}`;

                let localizedLabel = this.lottoryLabel.node.getComponent(LocalizedLabel);
                localizedLabel.setTextKeyAndOption("home_lottery_pro_Rtext", rule.needElimTimes - GlobalData.tempElimiTimes_lottery);

                if (GlobalData.tempElimiTimes_lottery >= rule.needElimTimes) {

                    let config = await ServiceAPI.LotteryConfig(GlobalData.userId);
                    await Popup.Lotterypage(config);

                }
                break;
            }
        }

    }

    /** 更新钱数 */
    public updateCashLabel(newCashTotal: number, isstart = 0) {
        let subCash = newCashTotal - GlobalData.curCashTotal;
        this.scheduleOnce(() => {
            GlobalData.curCashTotal = newCashTotal;
            if (GlobalData.curCashTotal >= GlobalData.wdlevelCahs) {
                ClientAPI.Point(NCPoint.SYMBOLENOUGH, { userid: GlobalData.userId });
            }
            const currentCashString = this.curCashLabel.string || "0";
            const currentCash = parseFloat(currentCashString.replace(/[^\d.-]/g, '')) || 0;

            const duration = 0.25;

            // 强制更新初始显示，确保标签内容显示正确
            // console.log(currentCash, newCashTotal);

            if (currentCash === newCashTotal) {
                this.curCashLabel.string = this.formatCashValue(newCashTotal);
                return;
            }

            if (isstart == 1) {
                this.curCashLabel.string = this.formatCashValue(newCashTotal);
            } else {
                // 启动 tween，并确保在 onUpdate 中进行更新
                tween({ value: currentCash })
                    .to(duration, { value: newCashTotal }, {
                        onUpdate: (target: { value: number }) => {
                            let formattedValue = this.formatCashValue(target.value);
                            // console.log(formattedValue);
                            this.curCashLabel.string = formattedValue;
                        }
                    })
                    .start();
            }

            this.updateDialogLabel();
        }, 0.5)
        this.scheduleOnce(() => {
            if (isstart == 0) {
                this.createLabelTip1(subCash);
            }
        }, 1)
    }

    /** 检查是否是新的一天并更新今日最高分 */
    public checkAndUpdateDailyHighScore(lastLoginDate: string): void {
        // 更新当前得分
        this.curScore = GlobalData.curScore;
        // 获取当前日期
        const currentDate = new Date().toDateString();

        // 检查是否是同一天
        console.log('是否是同一天：', lastLoginDate == currentDate);

        if (lastLoginDate !== currentDate) {//不是同一天
            GlobalData.todayHighScore = 0;
            LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);

        } else {
            if (GlobalData.curScore >= GlobalData.todayHighScore) {
                GlobalData.todayHighScore = GlobalData.curScore;
                LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);
            }
        }

        // 更新最后登录日期
        LocalStorageMgr.setItem(LocalStorageMgr.lastLoginDate_key, currentDate);
        this.updateScoreLabel(this.historyScoreLabel, GlobalData.historyHighScore);
        this.updateScoreLabel(this.todayScoreLabel, GlobalData.todayHighScore);
        this.updateScoreLabel(this.curScoreLabel, GlobalData.curScore);

    }

    /** 更新分数 */
    public updateScores(addScore: number): void {
        // 更新当前得分
        this.curScore += addScore;
        GlobalData.curScore = this.curScore;
        // 更新今日最高分
        if (this.curScore > GlobalData.todayHighScore) {
            GlobalData.todayHighScore = this.curScore;
            this.updateScoreLabel(this.todayScoreLabel, this.curScore)
        }

        // 更新历史最高分
        if (this.curScore > GlobalData.historyHighScore) {
            GlobalData.historyHighScore = this.curScore;
            this.updateScoreLabel(this.historyScoreLabel, this.curScore)
        }

        this.updateScoreLabel(this.curScoreLabel, this.curScore);

        // 保存分数的方法
        LocalStorageMgr.setItem(LocalStorageMgr.historyHighScore_key, GlobalData.historyHighScore);
        LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);
        LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore);
    }

    /**
     * 更新分数标签，使其逐渐增长到新分数
     * @param tarLabel 目标标签
     * @param newScore 新分数
     * @param duration 动画持续时间
     */
    updateScoreLabel(tarLabel: Label, newScore: number, duration: number = 1): void {
        const currentScore = parseInt(tarLabel.string) || 0;
        const delta = newScore - currentScore;

        if (delta === 0) {
            return;
        }

        tween({ value: currentScore })
            .to(duration, { value: newScore }, {
                onUpdate: (target: { value: number }) => {
                    tarLabel.string = Math.floor(target.value).toString();
                }
            })
            .start();
    }

    /** 格式化钱数字符串 */
    /** 格式化钱数字符串 */
    public formatCashValue(value: number): string {
        let round = GlobalData.getDataStore().ConfCountry.round; // 是否需要取整：1-需要，0-不需要
        let front = GlobalData.getDataStore().ConfCountry.front; // 货币格式符号是否前置：1-前置，0-后置
        let thousand = GlobalData.getDataStore().ConfCountry.thousand; // 千位符号：1-".", 2-",", 3-" "
        let point = GlobalData.getDataStore().ConfCountry.point; // 小数点：1-".", 2-",", 3-" "
        let symbol = GlobalData.getDataStore().ConfCountry.symbol;

        // 取整处理
        if (round === 1) {
            value = Math.round(value);
        }

        // 小数点符号替换
        let decimalSymbol = point === 1 ? '.' : point === 2 ? ',' : ' ';
        let thousandSymbol = thousand === 1 ? '.' : thousand === 2 ? ',' : ' ';

        // 格式化数字
        let parts = value.toFixed(2).split('.');
        let integerPart = parts[0];
        let decimalPart = parts[1];

        // 如果小数部分为 "0" 或 "00"，则只显示整数部分，否则保留小数部分
        let formattedValue = decimalPart === "00" || (decimalPart.length === 1 && decimalPart[0] === '0')
            ? integerPart
            : `${integerPart}${decimalSymbol}${decimalPart.replace(/0+$/, '')}`;

        // 添加千位分隔符
        integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSymbol);

        // 根据前置/后置符号设置
        if (front === 1) {
            return `${symbol}${formattedValue}`;
        } else {
            return `${formattedValue}${symbol}`;
        }
    }

    /**
     * 检测邮箱或手机号是否符合规则
     * @param input
     * @returns
     */
    public determineInputType(input: string): "EMAIL" | "PHONE" | boolean {
        // 邮箱的正则表达式
        const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        // 电话号码的正则表达式（简单格式验证数字和可选的前导+号）
        const phonePattern = /^\+?\d{10,15}$/;

        // 定义每个国家对应的电话号码规则
        const countryPhoneRules: { [key in CountryType]?: RegExp } = {
            [CountryType.BR]: /^\d{10,11}$/, // Type_02
            [CountryType.US]: /^\d{10}$/,    // Type_03
            [CountryType.GB]: /^\d{10,11}$/, // Type_02
            [CountryType.CA]: /^\d{10}$/,    // Type_03
            [CountryType.AU]: /^\d{9}$/,     // Type_04
            [CountryType.JP]: /^\d{10,11}$/, // Type_02
            [CountryType.KR]: /^\d{7,9}$/,   // Type_05
            [CountryType.DE]: /^\d{8}$/,     // Type_06
            [CountryType.FR]: /^\d{10}$/     // Type_03
        };

        // 判断是否是邮箱
        if (emailPattern.test(input)) {
            return "EMAIL";
        }

        // 判断是否是电话号码
        else if (phonePattern.test(input)) {
            const curCountry = I18n.curCountry; // 获取当前国家代码

            if (curCountry && countryPhoneRules[curCountry]) {
                const rule = countryPhoneRules[curCountry];

                // 先尝试匹配带区号的号码
                const withoutCountryCode = input.replace(/^\+?\d{1,4}/, ''); // 去掉可能存在的区号

                if (rule.test(withoutCountryCode)) {
                    return "PHONE";
                } else if (rule.test(input)) {
                    return "PHONE";
                } else {
                    return false; // 电话号码不符合当前国家的规则
                }
            }
            return "PHONE"; // 默认返回 PHONE
        } else {
            return false; // 输入既不是有效的邮箱也不是有效的电话号码
        }
    }


    /**
    * 替换 label 或 rich text 中的占位符，如 ${1}, ${2}。
    *
    * @param label - Label 或 RichText 组件。
    * @param replacements - 用于替换占位符的值。
    */
    replaceLabelString(label: Label | RichText, ...replacements: Array<string | number>): void {
        const originalString = label.string;  // 存储包含占位符的原始字符串

        let updatedString = originalString;

        // 动态替换占位符
        replacements.forEach((replacement, index) => {
            const placeholder = new RegExp(`\\$\\{${index + 1}\\}`, 'g');  // 创建动态占位符模式
            updatedString = updatedString.replace(placeholder, replacement.toString());
        });

        label.string = updatedString;
    }

    /** 更新任务进度 */
    updateMissionStatus(curtaskId: number, param: number | boolean) {
        if (typeof param === "number") {
            // 遍历每条任务数据，判断 curEliminateCount 是否满足条件
            GlobalData.missionData.forEach(mission => {
                if (param >= mission.eliminateCount) {
                    mission.isComplete = true;
                }
                if (param >= mission.eliminateCount && !mission.isGetReward) {
                    ClientAPI.Point(NCPoint.TASKCOMPLETE, { userid: GlobalData.userId });
                }
            });
        } else if (typeof param === "boolean") {
            // 根据 curtaskId 找到对应任务，并更新 isGetReward
            const mission = GlobalData.missionData.find(mission => mission.taskId === curtaskId);
            if (mission) {
                mission.isGetReward = param;
            }
        }
    }
}


